#encoding:utf-8
'''
FileName:channelasync.py
Creator:王烨
Date:2010.5.23
'''

from twisted.internet.defer import Deferred
from twisted.protocols.basic import Int32StringReceiver
from twisted.python.failure import Failure
import channel
from error import *
from rpc_pb2 import *

class ChannelAsync(channel.Channel, Int32StringReceiver):
    def __init__(self):
        channel.Channel.__init__(self)
        self.__pending = {}
        
    def Close(self):
        d = Deferred()
        d.addCallback(self.__CloseConnection)
        
    def __CloseConnection(self):
        self.transport.loseConnection()
    
    def connectionMade(self):
        peer = self.transport.getPeer()
        print '{0}:{1} connected'.format(peer.host, peer.port)
        
    def connectionLost(self, reason):
        print 'Connection closed'
        
    def CallMethod(self, methodDescriptor, controller, parameters, resultClass, done):
        '''执行RPC'''
        print '开始执行RPC'
        d = Deferred()
        d.addCallback(self.DeserializeResult, resultClass , controller)
        d.addCallback(done)
        d.addErrback(self.__HandleError)
        (uuid, request) = self.SerializeParameters(methodDescriptor, parameters)
        self.__pending[uuid] = d
        self.sendString(request)
        print '发送请求完毕'
        
    def stringReceived(self, data):
        print '开始接收响应'
        try:
            response = self.DeserializeResponse(data)
            uuid = response.uuid
            if self.__pending.has_key(uuid):
                print '开始回调'
                self.__pending[uuid].callback(response)
            else:
                raise ProtobufError(BAD_RESPONSE_PROTOCOL, '无效的响应uuid')
        except ProtobufError as err:
            failure = Failure(err)
            self.__HandleError(failure)
        
    def __HandleError(self, failure):
        print 'Error:',failure.getErrorMessage()